package com.matt.foundation.utils.export;

import com.matt.foundation.utils.ImgUtil;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYImageAnnotation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.ui.RectangleAnchor;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Locale;


public class LineChartXY {
	private static XYSeriesCollection createDataset(String[] lineNames, int [] month, double [][] values){

		XYSeriesCollection xyseriescollection = new XYSeriesCollection();

		for (int i = 0; i < lineNames.length; i++){
			String name = lineNames[i];
			XYSeries xyseries = new XYSeries(name, true, false);

			double[] lineDatas = values[i];

			for( int j = 0; j < month.length && month[j] <= 36; j++){
				xyseries.add(month[j], lineDatas[j]);
			}

			xyseriescollection.addSeries(xyseries);
		}

		return xyseriescollection;
	}



	public static JFreeChart createChart(int [] month, String[] lineNames, double [][] values, String xUnit, String yUnit,
										 float annX, float annY) {

		if (month == null) {
			month = new int[]{1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 21, 24, 30, 36};
		}

		// 2：创建Chart[创建不同图形]
		XYSeriesCollection dataset = createDataset(lineNames, month, values);
		JFreeChart chart = ChartFactory.createXYLineChart(null, null, null,
				dataset, PlotOrientation.VERTICAL, true, true, false);

		// 3:设置抗锯齿，防止字体显示不清楚
		ChartUtils.setAntiAlias(chart);// 抗锯齿

		// 4:对柱子进行渲染[[采用不同渲染]]
		ChartUtils.setLineRender(chart.getXYPlot(), false, true);//

		// 5:对其他部分进行渲染
		ChartUtils.setXAixs(chart.getXYPlot());// X坐标轴渲染
		ChartUtils.setYAixs(chart.getXYPlot());// Y坐标轴渲染

		// 设置标注无边框
		chart.getLegend().setFrame(new BlockBorder(Color.WHITE));

		//坐标系
		XYPlot xyplot = chart.getXYPlot();
		xyplot.setBackgroundPaint(Color.white);
		xyplot.setDomainGridlinePaint(Color.lightGray);

		((NumberAxis) xyplot.getDomainAxis()).setNumberFormatOverride(new ValuePNumberFormat(xUnit));
		((NumberAxis) xyplot.getRangeAxis()).setNumberFormatOverride(new ValuePNumberFormat(yUnit));

		NumberAxis numberaxis = (NumberAxis) xyplot.getDomainAxis();
		numberaxis.setUpperMargin(0.12D);
		numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits(Locale.CHINESE));

		NumberAxis numberaxis1 = (NumberAxis) xyplot.getRangeAxis();
		numberaxis1.setAutoRangeIncludesZero(false);
		numberaxis1.setStandardTickUnits(NumberAxis.createIntegerTickUnits(Locale.CHINESE));

		//图片指示器
//		Image anno_image = null;
//		try {
//			anno_image = ImageIO.read(new File("/tmp/mark.png"));
//			anno_image = anno_image.getScaledInstance(30, 30, Image.SCALE_SMOOTH);
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		XYImageAnnotation bg_ann = new XYImageAnnotation(annX, annY, anno_image, RectangleAnchor.CENTER);

		Image anno_image = ImgUtil.loadImageFromClassPath("freemarker/annotation.png");
		XYImageAnnotation bg_ann = new XYImageAnnotation(annX, annY, anno_image, RectangleAnchor.BOTTOM);

		xyplot.addAnnotation(bg_ann);

		return chart;
	}

	public static BufferedImage createChartBufferedImage(int [] month, String[] lineNames, double [][] values, String xUnit, String yUnit,
														 float annX, float annY){
		JFreeChart chart = createChart(month, lineNames, values, xUnit, yUnit, annX, annY);

		//输出文件
		BufferedImage image = new BufferedImage(1300, 500, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2 = image.createGraphics();

		g2.setRenderingHint(JFreeChart.KEY_SUPPRESS_SHADOW_GENERATION, true);
		Rectangle r = new Rectangle(0, 0, 1300, 500);
		chart.draw(g2, r);

		return image;
	}
}

class ValuePNumberFormat extends NumberFormat {

	private String unit ;

	ValuePNumberFormat(String unit){
		this.unit = unit;
	}

	@Override
	public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
		return toAppendTo.append(String.format("%.0f %s", number, unit));
	}

	@Override
	public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
		return toAppendTo.append(String.format("%ld %s", number, unit));
	}

	@Override
	public Number parse(String source, ParsePosition parsePosition) {
		String[] comps = source.split(" ");
		return Integer.parseInt(comps[0]);
	}
}